package com.aiapphub.SystemCode.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Dify 对话会话服务
 * 基于 Dify API 实现对话列表、归档列表等功能
 */
@Slf4j
@Service
public class DifyConversationService {
    
    @Value("${dify.api.key:}")
    private String difyApiKey;
    
    @Value("${dify.api.url:}")
    private String difyApiUrl;
    
    private OkHttpClient httpClient;
    
    @PostConstruct
    public void init() {
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .build();
        
        if (difyApiKey != null && !difyApiKey.trim().isEmpty() &&
            difyApiUrl != null && !difyApiUrl.trim().isEmpty()) {
            log.info("Dify对话服务初始化成功");
        } else {
            log.warn("Dify API密钥或连接地址未配置，对话服务未初始化");
        }
    }
    
    /**
     * 获取用户会话列表
     * @param userId 用户ID
     * @param limit 返回数量限制
     * @param apiKey 使用的 API Key（如果为 null，则使用默认配置的 apiKey）
     * @return 会话列表
     */
    public List<Map<String, Object>> getConversationsByUserId(String userId, Integer limit, String apiKey) {
        return getConversationsByUserId(userId, limit, apiKey, null);
    }
    
    /**
     * 获取用户会话列表
     * @param userId 用户ID
     * @param limit 返回数量限制
     * @param apiKey 使用的 API Key（如果为 null，则使用默认配置的 apiKey）
     * @param apiBaseUrl API基础URL（如果为 null，则使用默认配置的 difyApiUrl）
     * @return 会话列表
     */
    public List<Map<String, Object>> getConversationsByUserId(String userId, Integer limit, String apiKey, String apiBaseUrl) {
        try {
            // 如果传入了 apiKey，使用传入的；否则使用默认配置的
            String actualApiKey = (apiKey != null && !apiKey.trim().isEmpty()) ? apiKey : difyApiKey;
            
            if (actualApiKey == null || actualApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            // 如果传入了 apiBaseUrl，使用传入的；否则使用默认配置的
            String actualApiUrl = (apiBaseUrl != null && !apiBaseUrl.trim().isEmpty()) ? apiBaseUrl : difyApiUrl;
            
            if (actualApiUrl == null || actualApiUrl.trim().isEmpty()) {
                log.error("Dify API地址未配置");
                throw new RuntimeException("Dify API地址未配置");
            }
            
            String url = actualApiUrl + "/conversations?user=" + userId + "&limit=" + (limit != null ? limit : 20);
            
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .addHeader("Authorization", "Bearer " + actualApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = response.body().string();
                    log.info("获取会话列表成功，响应: {}", responseBody);
                    
                    JSONObject jsonResponse = JSON.parseObject(responseBody);
                    JSONArray dataArray = jsonResponse.getJSONArray("data");
                    
                    List<Map<String, Object>> conversations = new ArrayList<>();
                    if (dataArray != null) {
                        for (int i = 0; i < dataArray.size(); i++) {
                            JSONObject conversation = dataArray.getJSONObject(i);
                            Map<String, Object> convMap = new HashMap<>();
                            convMap.put("id", conversation.getString("id"));
                            convMap.put("name", conversation.getString("name"));
                            convMap.put("inputs", conversation.getJSONObject("inputs"));
                            convMap.put("status", conversation.getString("status"));
                            convMap.put("created_at", conversation.getLong("created_at"));
                            convMap.put("updated_at", conversation.getLong("updated_at"));
                            conversations.add(convMap);
                        }
                    }
                    
                    return conversations;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("获取会话列表失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    
                    // 根据HTTP状态码提供更具体的错误信息
                    String errorMessage;
                    if (response.code() == 401) {
                        errorMessage = "API认证失败，请检查Dify API密钥配置";
                    } else if (response.code() == 403) {
                        errorMessage = "API访问被拒绝，请检查权限配置";
                    } else if (response.code() == 404) {
                        errorMessage = "API接口不存在，请检查Dify API地址配置";
                    } else if (response.code() >= 500) {
                        errorMessage = "Dify服务器内部错误，请稍后重试";
                    } else {
                        errorMessage = "获取会话列表失败: " + errorBody;
                    }
                    
                    throw new RuntimeException(errorMessage);
                }
            }
            
        } catch (IOException e) {
            log.error("获取会话列表网络异常", e);
            if (e.getMessage().contains("timeout")) {
                throw new RuntimeException("请求超时，请检查网络连接", e);
            } else {
                throw new RuntimeException("网络连接失败: " + e.getMessage(), e);
            }
        }
    }
    
    /**
     * 获取会话详情
     * @param conversationId 会话ID
     * @param userId 用户ID
     * @return 会话详情
     */
    public Map<String, Object> getConversationById(String conversationId, String userId) {
        try {
            if (difyApiKey == null || difyApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations/" + conversationId + "?user=" + userId;
            
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .addHeader("Authorization", "Bearer " + difyApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = response.body().string();
                    log.info("获取会话详情成功，响应: {}", responseBody);
                    
                    JSONObject jsonResponse = JSON.parseObject(responseBody);
                    Map<String, Object> conversation = new HashMap<>();
                    conversation.put("id", jsonResponse.getString("id"));
                    conversation.put("name", jsonResponse.getString("name"));
                    conversation.put("inputs", jsonResponse.getJSONObject("inputs"));
                    conversation.put("status", jsonResponse.getString("status"));
                    conversation.put("created_at", jsonResponse.getLong("created_at"));
                    conversation.put("updated_at", jsonResponse.getLong("updated_at"));
                    
                    return conversation;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("获取会话详情失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    throw new RuntimeException("获取会话详情失败: " + errorBody);
                }
            }
            
        } catch (IOException e) {
            log.error("获取会话详情异常", e);
            throw new RuntimeException("获取会话详情失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 删除会话
     * @param conversationId 会话ID
     * @param userId 用户ID
     * @param apiKey 使用的 API Key（如果为 null，则使用默认配置的 apiKey）
     * @return 删除结果
     */
    public boolean deleteConversation(String conversationId, String userId, String apiKey) {
        try {
            // 如果传入了 apiKey，使用传入的；否则使用默认配置的
            String actualApiKey = (apiKey != null && !apiKey.trim().isEmpty()) ? apiKey : difyApiKey;
            
            if (actualApiKey == null || actualApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations/" + conversationId;
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("user", userId);
            
            String jsonBody = JSON.toJSONString(requestBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
            
            Request request = new Request.Builder()
                    .url(url)
                    .delete(body)
                    .addHeader("Authorization", "Bearer " + actualApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    log.info("删除会话成功，会话ID: {}", conversationId);
                    return true;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("删除会话失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    return false;
                }
            }
            
        } catch (IOException e) {
            log.error("删除会话异常", e);
            throw new RuntimeException("删除会话失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 重命名会话
     * @param conversationId 会话ID
     * @param name 新名称
     * @param userId 用户ID
     * @param autoGenerate 是否自动生成名称
     * @param apiKey 使用的 API Key（如果为 null，则使用默认配置的 apiKey）
     * @return 重命名结果
     */
    public boolean renameConversation(String conversationId, String name, String userId, boolean autoGenerate, String apiKey) {
        try {
            // 如果传入了 apiKey，使用传入的；否则使用默认配置的
            String actualApiKey = (apiKey != null && !apiKey.trim().isEmpty()) ? apiKey : difyApiKey;
            
            if (actualApiKey == null || actualApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations/" + conversationId + "/name";
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("name", name);
            requestBody.put("auto_generate", autoGenerate);
            requestBody.put("user", userId);
            
            String jsonBody = JSON.toJSONString(requestBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
            
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Authorization", "Bearer " + actualApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    log.info("重命名会话成功，会话ID: {}, 新名称: {}", conversationId, name);
                    return true;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("重命名会话失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    return false;
                }
            }
            
        } catch (IOException e) {
            log.error("重命名会话异常", e);
            throw new RuntimeException("重命名会话失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取归档会话列表
     * @param userId 用户ID
     * @param limit 返回数量限制
     * @return 归档会话列表
     */
    public List<Map<String, Object>> getArchivedConversations(String userId, Integer limit) {
        try {
            if (difyApiKey == null || difyApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations?user=" + userId + "&limit=" + (limit != null ? limit : 20) + "&status=archived";
            
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .addHeader("Authorization", "Bearer " + difyApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = response.body().string();
                    log.info("获取归档会话列表成功，响应: {}", responseBody);
                    
                    JSONObject jsonResponse = JSON.parseObject(responseBody);
                    JSONArray dataArray = jsonResponse.getJSONArray("data");
                    
                    List<Map<String, Object>> conversations = new ArrayList<>();
                    if (dataArray != null) {
                        for (int i = 0; i < dataArray.size(); i++) {
                            JSONObject conversation = dataArray.getJSONObject(i);
                            Map<String, Object> convMap = new HashMap<>();
                            convMap.put("id", conversation.getString("id"));
                            convMap.put("name", conversation.getString("name"));
                            convMap.put("inputs", conversation.getJSONObject("inputs"));
                            convMap.put("status", conversation.getString("status"));
                            convMap.put("created_at", conversation.getLong("created_at"));
                            convMap.put("updated_at", conversation.getLong("updated_at"));
                            conversations.add(convMap);
                        }
                    }
                    
                    return conversations;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("获取归档会话列表失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    throw new RuntimeException("获取归档会话列表失败: " + errorBody);
                }
            }
            
        } catch (IOException e) {
            log.error("获取归档会话列表异常", e);
            throw new RuntimeException("获取归档会话列表失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 归档会话
     * @param conversationId 会话ID
     * @param userId 用户ID
     * @return 归档结果
     */
    public boolean archiveConversation(String conversationId, String userId) {
        try {
            if (difyApiKey == null || difyApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations/" + conversationId + "/archive";
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("user", userId);
            
            String jsonBody = JSON.toJSONString(requestBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
            
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Authorization", "Bearer " + difyApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    log.info("归档会话成功，会话ID: {}", conversationId);
                    return true;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("归档会话失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    return false;
                }
            }
            
        } catch (IOException e) {
            log.error("归档会话异常", e);
            throw new RuntimeException("归档会话失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 恢复归档的会话
     * @param conversationId 会话ID
     * @param userId 用户ID
     * @return 恢复结果
     */
    public boolean unarchiveConversation(String conversationId, String userId) {
        try {
            if (difyApiKey == null || difyApiKey.trim().isEmpty()) {
                log.error("Dify API密钥未配置");
                throw new RuntimeException("Dify API密钥未配置");
            }
            
            String url = difyApiUrl + "/conversations/" + conversationId + "/unarchive";
            
            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("user", userId);
            
            String jsonBody = JSON.toJSONString(requestBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
            
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Authorization", "Bearer " + difyApiKey)
                    .addHeader("Content-Type", "application/json")
                    .build();
            
            try (Response response = httpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    log.info("恢复归档会话成功，会话ID: {}", conversationId);
                    return true;
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "Unknown error";
                    log.error("恢复归档会话失败，状态码: {}, 错误信息: {}", response.code(), errorBody);
                    return false;
                }
            }
            
        } catch (IOException e) {
            log.error("恢复归档会话异常", e);
            throw new RuntimeException("恢复归档会话失败: " + e.getMessage(), e);
        }
    }
}
